package examples;

import javax.swing.JFrame;

import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.DataSizeAction;
import prefuse.action.layout.graph.NodeLinkTreeLayout;
import prefuse.data.Graph;
import prefuse.data.Node;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.LabelRenderer;
import prefuse.util.ColorLib;
import prefuse.visual.VisualItem;

public class HelloWorldPrefuseNodeSize extends Display {
    private static final String SIZE = "size";

    private static final String LABEL = "label";

    Graph graph;

    public static final String GRAPH = "graph";

    public static final String NODES = "graph.nodes";

    public static final String EDGES = "graph.edges";

    public HelloWorldPrefuseNodeSize() {
        // setup a visualisation
        super(new Visualization());
        // generate a graph
        initGraph();

        //  standard labelRenderer for the given label
        LabelRenderer nodeRenderer = new LabelRenderer(LABEL);
        // rendererFactory for the visualization items 
        DefaultRendererFactory rendererFactory = new DefaultRendererFactory();
        // set the labelRenderer
        rendererFactory.setDefaultRenderer(nodeRenderer);
        m_vis.setRendererFactory(rendererFactory);

        // Color Actions
        ColorAction nodeText = new ColorAction(NODES, VisualItem.TEXTCOLOR);
        nodeText.setDefaultColor(ColorLib.gray(0));
        ColorAction nodeStroke = new ColorAction(NODES, VisualItem.STROKECOLOR);
        nodeStroke.setDefaultColor(ColorLib.gray(100));
        ColorAction nodeFill = new ColorAction(NODES, VisualItem.FILLCOLOR);
        nodeFill.setDefaultColor(ColorLib.gray(255));
        ColorAction edgeStrokes = new ColorAction(EDGES, VisualItem.STROKECOLOR);
        edgeStrokes.setDefaultColor(ColorLib.gray(100));

        // bundle the color actions
        ActionList draw = new ActionList();
        draw.add(nodeText);
        draw.add(nodeStroke);
        draw.add(nodeFill);
        draw.add(edgeStrokes);

        // DataSizeAction
        DataSizeAction nodeDataSizeAction = new DataSizeAction(NODES, SIZE);
        draw.add(nodeDataSizeAction);
        m_vis.putAction("draw", draw);

        // create the layout action for the graph
        NodeLinkTreeLayout treeLayout = new NodeLinkTreeLayout(GRAPH);
        m_vis.putAction("treeLayout", treeLayout);

        // run actions
        m_vis.run("treeLayout");
        m_vis.run("draw");
        
    }

    private void initGraph() {
        graph = new Graph();
        // first define a column
        graph.addColumn(LABEL, String.class);
        graph.addColumn(SIZE, int.class);
        // then add nodes
        Node h = addNode("h", 20);
        Node e = addNode("e", 4);
        Node l1 = addNode("l", 4);
        Node l2 = addNode("l", 5);;
        Node o1 = addNode("o", 10);
        Node blank = addNode(" ", 40);
        Node w = addNode("w", 5);
        Node o2 = addNode("o", 24);
        Node r = addNode("r", 42);
        Node l3 = addNode("l", 17);
        Node d = addNode("d", 34);

        // then add the edges
        graph.addEdge(h, e);
        graph.addEdge(e, l1);
        graph.addEdge(l1, l2);
        graph.addEdge(l2, o1);
        graph.addEdge(o1, blank);
        graph.addEdge(blank, w);
        graph.addEdge(w, o2);
        graph.addEdge(o2, r);
        graph.addEdge(r, l3);
        graph.addEdge(l3, d);

        m_vis.addGraph(GRAPH, graph);

    }

    private Node addNode(String label, int size) {
        Node node = graph.addNode();
        node.setString(LABEL, label);
        node.setInt(SIZE, size);
        return node;
    }

    public static void main(String[] args) {
        HelloWorldPrefuseNodeSize hello = new HelloWorldPrefuseNodeSize();
        JFrame frame = new JFrame("Hello World");
        frame.getContentPane().add(hello);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocation(10,10);
        frame.setSize(800,400);
        frame.setVisible(true);
    }

}